﻿ 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
using Newtonsoft.Json.Linq;

namespace Sky.FanQieDownload
{
    public partial class MainForm : Form
    {
        private FanqieNovelDownloader _downloader;
        private BindingList<DownloadTask> _downloadTasks;

        public MainForm()
        {
            InitializeComponent();
            InitializeApp();
        }

        private void InitializeApp()
        {
            _downloader = new FanqieNovelDownloader();
            _downloadTasks = new BindingList<DownloadTask>();
            dataGridViewTasks.DataSource = _downloadTasks;

            // 设置并发数
            numericUpDownConcurrent.Value = 5;

            // 设置保存路径
            textBoxSavePath.Text = Path.Combine(Environment.CurrentDirectory, "Downloads");
        }

        private async void buttonStartDownload_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrWhiteSpace(textBoxUrl.Text))
            {
                MessageBox.Show("请输入URL或选择文件", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            buttonStartDownload.Enabled = false;
            try
            {
                await ProcessDownloadInput(textBoxUrl.Text.Trim());
            }
            catch (Exception ex)
            {
                LogMessage($"错误: {ex.Message}", Color.Red);
            }
            finally
            {
                buttonStartDownload.Enabled = true;
            }
        }

        private async Task ProcessDownloadInput(string input)
        {
            if (File.Exists(input) && Path.GetExtension(input).ToLower() == ".txt")
            {
                // 批量下载模式
                await ProcessBatchDownload(input);
            }
            else
            {
                // 单本下载模式
                await ProcessSingleDownload(input);
            }
        }

        private async Task ProcessBatchDownload(string filePath)
        {
            var urls = await File.ReadAllLinesAsync(filePath);
            var validUrls = urls.Where(url => !string.IsNullOrWhiteSpace(url)).ToArray();

            LogMessage($"发现 {validUrls.Length} 个下载任务", Color.Blue);

            var progressHandler = new Progress<DownloadProgress>(UpdateProgress);

            for (int i = 0; i < validUrls.Length; i++)
            {
                var url = validUrls[i].Trim();
                LogMessage($"开始下载 ({i + 1}/{validUrls.Length}): {url}", Color.Green);

                var task = new DownloadTask
                {
                    Url = url,
                    Status = "下载中",
                    Progress = 0
                };
                _downloadTasks.Add(task);

                try
                {
                    var result = await _downloader.DownloadNovelAsync(url, progressHandler);

                    task.Status = result.Success ? "完成" : "失败";
                    task.Progress = 100;
                    task.BookName = result.BookName;

                    if (result.Success)
                    {
                        LogMessage($"下载完成: {result.BookName} ({result.TotalChapters}章, 耗时: {result.ElapsedTime:hh\\:mm\\:ss})", Color.Green);
                    }
                    else
                    {
                        LogMessage($"下载失败: {result.ErrorMessage}", Color.Red);
                    }
                }
                catch (Exception ex)
                {
                    task.Status = "错误";
                    task.Progress = 100;
                    LogMessage($"下载出错: {ex.Message}", Color.Red);
                }

                // 刷新DataGridView
                dataGridViewTasks.Refresh();
            }

            LogMessage("所有任务完成!", Color.Blue);
        }

        private async Task ProcessSingleDownload(string url)
        {
            var task = new DownloadTask
            {
                Url = url,
                Status = "下载中",
                Progress = 0
            };
            _downloadTasks.Add(task);

            var progressHandler = new Progress<DownloadProgress>(UpdateProgress);

            try
            {
                var result = await _downloader.DownloadNovelAsync(url, progressHandler);

                task.Status = result.Success ? "完成" : "失败";
                task.Progress = 100;
                task.BookName = result.BookName;

                if (result.Success)
                {
                    LogMessage($"下载完成: {result.BookName} ({result.TotalChapters}章, 耗时: {result.ElapsedTime:hh\\:mm\\:ss})", Color.Green);
                }
                else
                {
                    LogMessage($"下载失败: {result.ErrorMessage}", Color.Red);
                }
            }
            catch (Exception ex)
            {
                task.Status = "错误";
                task.Progress = 100;
                LogMessage($"下载出错: {ex.Message}", Color.Red);
            }

            dataGridViewTasks.Refresh();
        }

        private void UpdateProgress(DownloadProgress progress)
        {
            if (InvokeRequired)
            {
                Invoke(new Action<DownloadProgress>(UpdateProgress), progress);
                return;
            }

            // 更新进度条
            progressBarDownload.Value = Math.Min((int)progress.Percentage, 100);
            labelProgress.Text = $"进度: {progress.Current}/{progress.Total} ({progress.Percentage:F1}%)";

            // 更新当前任务状态
            var currentTask = _downloadTasks.LastOrDefault();
            if (currentTask != null)
            {
                currentTask.Progress = (int)progress.Percentage;
                dataGridViewTasks.Refresh();
            }
        }

        private void LogMessage(string message, Color color)
        {
            if (textBoxLog.InvokeRequired)
            {
                textBoxLog.Invoke(new Action<string, Color>(LogMessage), message, color);
                return;
            }

            textBoxLog.SelectionStart = textBoxLog.TextLength;
            textBoxLog.SelectionLength = 0;
            //textBoxLog.SelectionColor = color;
            textBoxLog.AppendText($"{DateTime.Now:HH:mm:ss} - {message}{Environment.NewLine}");
            //textBoxLog.SelectionColor = textBoxLog.ForeColor;
            textBoxLog.ScrollToCaret();
        }

        private void buttonBrowseFile_Click(object sender, EventArgs e)
        {
            using (var openFileDialog = new OpenFileDialog())
            {
                openFileDialog.Filter = "文本文件 (*.txt)|*.txt|所有文件 (*.*)|*.*";
                openFileDialog.Title = "选择包含URL的文本文件";

                if (openFileDialog.ShowDialog() == DialogResult.OK)
                {
                    textBoxUrl.Text = openFileDialog.FileName;
                }
            }
        }

        private void buttonBrowseFolder_Click(object sender, EventArgs e)
        {
            using (var folderDialog = new FolderBrowserDialog())
            {
                folderDialog.Description = "选择小说保存目录";
                folderDialog.SelectedPath = textBoxSavePath.Text;

                if (folderDialog.ShowDialog() == DialogResult.OK)
                {
                    textBoxSavePath.Text = folderDialog.SelectedPath;
                    _downloader.SetSavePath(folderDialog.SelectedPath);
                }
            }
        }

        private void buttonClearLog_Click(object sender, EventArgs e)
        {
            textBoxLog.Clear();
        }

        private void numericUpDownConcurrent_ValueChanged(object sender, EventArgs e)
        {
            _downloader.SetConcurrentDownloads((int)numericUpDownConcurrent.Value);
        }
    }
    public class DataGridViewProgressColumn : DataGridViewImageColumn
    {
        public DataGridViewProgressColumn()
        {
            CellTemplate = new DataGridViewProgressCell();
        }
    }

    public class DataGridViewProgressCell : DataGridViewImageCell
    {
        protected override object GetFormattedValue(object value,
            int rowIndex, ref DataGridViewCellStyle cellStyle,
            System.ComponentModel.TypeConverter valueTypeConverter,
            System.ComponentModel.TypeConverter formattedValueTypeConverter,
            DataGridViewDataErrorContexts context)
        {
            return null;
        }

        protected override void Paint(Graphics g, Rectangle clipBounds,
            Rectangle cellBounds, int rowIndex,
            DataGridViewElementStates elementState, object value,
            object formattedValue, string errorText,
            DataGridViewCellStyle cellStyle,
            DataGridViewAdvancedBorderStyle advancedBorderStyle,
            DataGridViewPaintParts paintParts)
        {
            int progressVal = 0;
            if (value != null && int.TryParse(value.ToString(), out progressVal))
            {
                float percentage = progressVal / 100.0f;
                Brush backColorBrush = new SolidBrush(cellStyle.BackColor);
                Brush foreColorBrush = new SolidBrush(cellStyle.ForeColor);

                g.FillRectangle(backColorBrush, cellBounds.X, cellBounds.Y, cellBounds.Width, cellBounds.Height);

                if (percentage > 0)
                {
                    g.FillRectangle(Brushes.LightGreen, cellBounds.X + 2, cellBounds.Y + 2,
                        Convert.ToInt32((percentage * cellBounds.Width - 4)), cellBounds.Height - 4);
                }

                g.DrawString(progressVal + "%", cellStyle.Font, foreColorBrush,
                    cellBounds.X + (cellBounds.Width / 2) - 20, cellBounds.Y + 2);

                backColorBrush.Dispose();
                foreColorBrush.Dispose();
            }
            else
            {
                base.Paint(g, clipBounds, cellBounds, rowIndex, elementState,
                    value, formattedValue, errorText, cellStyle,
                    advancedBorderStyle, paintParts);
            }
        }
    }
    public class DownloadTask
    {
        public string Url { get; set; }
        public string BookName { get; set; }
        public string Status { get; set; }
        public int Progress { get; set; }
    }
}
